package pool

import (
	"github.com/zeromicro/go-zero/core/threading"
)

// goroutine pool
// 协程池

var DefaultRoutinePool = New(128)

func New(size int) *RoutinePool {
	return &RoutinePool{
		wch:     make(chan func()),
		limitCh: make(chan struct{}, size),
	}
}

type RoutinePool struct {
	// 调度chan
	wch chan func()
	// 限制chan，表示同时支持多少个协程调度
	limitCh chan struct{}
}

func (p *RoutinePool) Schedule(fn func()) {
	select {
	case p.wch <- fn:
	case p.limitCh <- struct{}{}:
		go p.worker(fn)
	}
}

func (p *RoutinePool) worker(fn func()) {
	defer func() { <-p.limitCh }()
	for {
		threading.RunSafe(fn)
		fn = <-p.wch
	}
}
